home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / source / Assembler.c < prev    next >
Encoding:
Text File  |  1994-10-04  |  11.8 KB  |  440 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    <ctype.h>
  13. #include    <stdlib.h>
  14.  
  15. #include    "UtilsSys7.h"
  16. #include    "Assembler.h"
  17. #include    "Disasm.h"
  18. #include    "Dump.h"
  19. #include    "DoEditDialog.h"
  20. #include    "Globals.h"
  21. #include    "Main.h"
  22. #include    "Microprogram_Ed.h"
  23. #include    "SimUtils.h"
  24. #include    "Conversions.h"
  25.  
  26. #if defined(FabSystem7orlater)
  27.  
  28. #pragma segment Rare
  29.  
  30. enum {
  31. kOPCMAXLEN = 4,
  32. kGROW_SYMTAB = 50,
  33. kGROW_OBJTAB = 150,
  34. kBITS_12 = 0x0FFF,
  35. kBITS_11 = 0x07FF,
  36. kBITS_8 = 0x00FF
  37. };
  38.  
  39. struct symtable {
  40.     StringHandle    symb;
  41.     long    value;
  42.     };
  43.  
  44. typedef struct symtable symtable;
  45. typedef symtable *symtablePtr;
  46. typedef symtablePtr *symtableHandle;
  47.  
  48. #if defined(powerc) || defined (__powerc)
  49. #pragma options align=mac68k
  50. #endif
  51. struct objtable {
  52.     long    operand;
  53.     Byte    length;
  54.     Byte    class;
  55.     unsigned short    opcod;
  56.     Boolean    isSymbol;
  57.     Boolean    reserved;
  58.     };
  59. #if defined(powerc) || defined(__powerc)
  60. #pragma options align=reset
  61. #endif
  62.  
  63. typedef struct objtable objtable;
  64. typedef objtable *objtablePtr;
  65. typedef objtablePtr *objtableHandle;
  66.  
  67. static OSErr OnePassAsm(Handle fileBuffer);
  68. static long CountReturns(Handle fileBuffer, char *lastpos);
  69. static pascal Boolean AsmEditNumFilter(DialogPtr, EventRecord *, short *);
  70. static int compareMnem(const void *opc1, const void *opc2);
  71. static int cmpsymb(const void *opc1, const void *opc2);
  72.  
  73.  
  74. /* myAsmFile: reads theFile to be assembled into memory */
  75.  
  76. OSErr myAsmFile(FSSpec *theFile)
  77. {
  78. ParamBlockRec    myPB;
  79. EventRecord    dummyEv;
  80. register Handle    tempBuffer;
  81. unsigned long    fileSize;
  82. short    asmFileRefN;
  83. register OSErr    err;
  84.  
  85. SetCursor(*gWatchHandle);
  86. if ((err = FSpOpenDF(theFile, fsRdPerm, &asmFileRefN)) == noErr) {
  87.     if ((err = GetEOF(asmFileRefN, (long *)&fileSize)) == noErr) {
  88.         if (tempBuffer = NewHandleGeneral(fileSize)) {
  89.             myPB.ioParam.ioCompletion = nil;
  90.             myPB.ioParam.ioRefNum = asmFileRefN;
  91.             HLock(tempBuffer);
  92.             myPB.ioParam.ioBuffer = *tempBuffer;
  93.             myPB.ioParam.ioReqCount = fileSize;
  94.             myPB.ioParam.ioPosMode = fsFromStart;
  95.             myPB.ioParam.ioPosOffset = 0L;
  96.             (void)PBReadAsync(&myPB);
  97.             while (myPB.ioParam.ioResult > 0) {
  98.                 SystemTask();
  99.                 (void)EventAvail(everyEvent, &dummyEv);
  100.                 }
  101.             HUnlock(tempBuffer);
  102.             if ((err = myPB.ioParam.ioResult) == noErr) {
  103.                 /* Do damned assembling */
  104.                 err = OnePassAsm(tempBuffer);
  105.                 InvalDump();
  106.                 InvalDisasm();
  107.                 }
  108.             DisposHandle(tempBuffer);
  109.             }
  110.         else err = MemError();
  111.         }
  112.     (void)FSClose(asmFileRefN);
  113.     }
  114. InitCursor();
  115. return(err);
  116. }
  117.  
  118. /* OnePassAsm: assembles the file passed in the buffer */
  119.  
  120. static OSErr OnePassAsm(Handle fileBuffer)
  121. {
  122. Str255    tempS;
  123. Handle    SortedOpcodeTable;
  124. symtableHandle    SymbolTable;
  125. objtableHandle    ObjTable;
  126. Handle    tempH;
  127. Ptr    myEOF;
  128. long    ILC;
  129. ROpcodePtr    found;
  130. symtablePtr    foundsym;
  131. Size    ObjTabOffset, SymTabOffset, tmpSize;
  132. short    build;
  133. short    numinstr;
  134. OSErr    err;
  135. register Byte    i;
  136. register char *ex = nil;
  137. register char *copy;
  138.  
  139. err = noErr;
  140. ILC = (long)gILCBase << 1;
  141. DetachResource(SortedOpcodeTable = Get1Resource(krInstructions, kOPCODES));
  142. HNoPurge(SortedOpcodeTable);
  143. qsort((*SortedOpcodeTable) + 2, numinstr = (*(unsigned short *)*SortedOpcodeTable) + 1,
  144.     sizeof(ROpcode), compareMnem);
  145.  
  146. /* init symbol & object table */
  147. if ((SymbolTable = (symtableHandle)NewHandleGeneral(sizeof(symtable)*kGROW_SYMTAB))) {
  148.     if ((ObjTable = (objtableHandle)NewHandleGeneral(sizeof(objtable)*kGROW_OBJTAB))) {
  149.         SymTabOffset = 0L;
  150.         ObjTabOffset = 0L;
  151.         HLock(fileBuffer);
  152.         ex = *fileBuffer;
  153.         myEOF = (Ptr)((Size)ex + InlineGetHandleSize(fileBuffer));
  154.         do {
  155.             if (*ex == 13)
  156.                 ex++;
  157.             else {
  158.                 if (ispunct(*ex))
  159.                     while (*ex++ != 13)
  160.                         ;
  161.                 else {
  162.                     if (isspace(*ex) == 0) {
  163.                         copy = (char *)&tempS[1];
  164.                         i = 0;
  165.                         do {
  166.                             *copy++ = *ex++;
  167.                             i++;
  168.                             }
  169.                         while (isspace(*ex) == 0);
  170.                         tempS[0] = i;
  171.                         /* add to symbol table */
  172.                         if (SymTabOffset >= (tmpSize = InlineGetHandleSize((Handle)SymbolTable)))
  173.                             SetHandleSize((Handle)SymbolTable, tmpSize + sizeof(symtable)*kGROW_SYMTAB);
  174.                         tempH = (Handle)NewString(tempS);
  175.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->symb = (StringHandle)tempH;
  176.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->value = ILC;
  177.                         SymTabOffset += sizeof(symtable);
  178.                         }
  179.                     if (*ex == 13)
  180.                         ex++;
  181.                     else {
  182.                         while (isspace(*ex++))
  183.                             ;
  184.                         --ex;
  185.                         copy = (char *)&tempS;
  186.                         i = 0;
  187.                         do {
  188.                             *copy++ = *ex++;
  189.                             i++;
  190.                             }
  191.                         while (isspace(*ex) == 0);
  192.                         if (i > kOPCMAXLEN) {
  193.                             err = kasmErrInvalidOpcode;
  194.                             break;
  195.                             }
  196.                         else {
  197.                             while (i < kOPCMAXLEN) {
  198.                                 i++;
  199.                                 *copy++ = ' ';
  200.                                 }
  201.                             if (ObjTabOffset >= (tmpSize = InlineGetHandleSize((Handle)ObjTable)))
  202.                                 SetHandleSize((Handle)ObjTable, tmpSize + sizeof(objtable)*kGROW_OBJTAB);
  203.                             found = (ROpcodePtr)bsearch(&tempS, (*SortedOpcodeTable)+2,
  204.                                     numinstr, sizeof(ROpcode), compareMnem);
  205.                             if (found == nil) {
  206.                                 err = kasmErrInvalidOpcode;
  207.                                 break;
  208.                                 }
  209.                             else {
  210.                                 *(long *)&((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->length = *(long *)(&found->length);
  211.                                 i = found->class;
  212.                                 if (i == kCLASS_16_0) {
  213.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  214.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = 0L;
  215.                                     }
  216.                                 else {
  217.                                     while (isspace(*ex++))
  218.                                         ;
  219.                                     --ex;
  220.                                     if (*ex == '#') {
  221.                                         ++ex;
  222.                                         copy = (char *)&tempS[1];
  223.                                         i = 0;
  224.                                         do {
  225.                                             *copy++ = *ex++;
  226.                                             i++;
  227.                                             }
  228.                                         while (isspace(*ex) == 0);
  229.                                         tempS[0] = i;
  230.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  231.                                         StringToNum(tempS, &((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand);
  232.                                         }
  233.                                     else {
  234.                                         copy = (char *)&tempS[1];
  235.                                         i = 0;
  236.                                         do {
  237.                                             *copy++ = *ex++;
  238.                                             i++;
  239.                                             }
  240.                                         while (isspace(*ex) == 0);
  241.                                         tempS[0] = i;
  242.                                         tempH = (Handle)NewString(tempS);
  243.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = true;
  244.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = (long)tempH;
  245.                                         }
  246.                                     }
  247.                                 ObjTabOffset += sizeof(objtable);
  248.                                 }
  249.                             while (*ex++ != 13)
  250.                                 ;
  251.                             ILC += found->length;
  252.                             }
  253.                         }
  254.                     }
  255.                 }
  256.             }
  257.         while (ex < myEOF);
  258.         HUnlock(fileBuffer);
  259.         if (err == noErr)
  260.             /* check for ILC out of bounds */
  261.             if (ILC > kSIZE_RAM - 4096)
  262.                 err = kasmErrPotHeapDamage;
  263.         if (err == noErr) {
  264.             ILC = (long)gILCBase << 1;
  265.             qsort(*SymbolTable, SymTabOffset / sizeof(symtable), sizeof(symtable), cmpsymb);
  266.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable)) {
  267.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol) {
  268.                     foundsym = (symtablePtr)
  269.                         bsearch(&((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand,
  270.                         *SymbolTable, SymTabOffset / sizeof(symtable),
  271.                         sizeof(symtable), cmpsymb);
  272.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol = false;
  273.                     DisposHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  274.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand =
  275.                             (foundsym ? (((objtablePtr)(*(Handle)ObjTable + tmpSize))->class >= kCLASS_16_16_REL
  276.                             ? (foundsym->value - ILC - ((objtablePtr)(*(Handle)ObjTable + tmpSize))->length) >> 1
  277.                             : foundsym->value) : (err = kasmErrSymbolNotDef, 0L));
  278.                     }
  279.                 switch (((objtablePtr)(*(Handle)ObjTable + tmpSize))->class) {
  280.                     case kCLASS_4_12:
  281.                     case kCLASS_4_12_REL:
  282.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  283.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_12));
  284.                         *(short *)(gMMemory + ILC) = build;
  285.                         ILC += 2;
  286.                         break;
  287.                     case kCLASS_5_11:
  288.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  289.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_11));
  290.                         *(short *)(gMMemory + ILC) = build;
  291.                         ILC += 2;
  292.                         break;
  293.                     case kCLASS_8_8:
  294.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  295.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_8));
  296.                         *(short *)(gMMemory + ILC) = build;
  297.                         ILC += 2;
  298.                         break;
  299.                     case kCLASS_16_0:
  300.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  301.                         ILC += 2;
  302.                         break;
  303.                     case kCLASS_16_16:
  304.                     case kCLASS_16_16_REL:
  305.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  306.                         ILC += 2;
  307.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand;
  308.                         ILC += 2;
  309.                         break;
  310.                     }
  311.                 }
  312.             }
  313.         if ((err != noErr) && (err != kasmErrSymbolNotDef))
  314.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable))
  315.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol)
  316.                     DisposHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  317.         for(tmpSize = 0; tmpSize < SymTabOffset; tmpSize += sizeof(symtable))
  318.             DisposHandle((Handle)((symtablePtr)(*(Handle)SymbolTable + tmpSize))->symb);
  319.         DisposHandle((Handle)ObjTable);
  320.         }
  321.     else err = MemError();
  322.     DisposHandle((Handle)SymbolTable);
  323.     }
  324. else err = MemError();
  325. DisposHandle(SortedOpcodeTable);
  326. if (err > 0) {
  327.     InitCursor();
  328.     if (ex)
  329.         MyNumToString(1L + CountReturns(fileBuffer, ex), tempS);
  330.     else
  331.         *(short *)tempS = 0x013F;
  332.     ParamText(tempS, nil, nil, nil);
  333.     StopAlert_UPP(kALRT_ASM + err, myStdFilterProcNoCancel);
  334.     err = 0;
  335.     }
  336. return err;
  337. }
  338.  
  339. static long CountReturns(Handle fileBuffer, char *lastpos)
  340. {
  341. register char *scanptr;
  342. register char *end = StripAddress(lastpos);
  343. register long    cnt = 0L;
  344.  
  345. for ( scanptr = StripAddress(*fileBuffer); scanptr <= end; )
  346.     if (*scanptr++ == 13)
  347.         ++cnt;
  348. return cnt;
  349. }
  350.  
  351.  
  352. enum {
  353. kDLOG_ASMPREFS = 134,
  354. kItemAsmDestLoc = 3
  355. };
  356.  
  357. void DoAsmPrefsDialog(void)
  358. {
  359. Str255    AsmDestStr;
  360.  
  361. dialogItems    things[] = {{ ok, 0, 1L },
  362.                         { cancel, 0, 0L },
  363.                         { kItemAsmDestLoc, 0, 0L },
  364.                         { 0, 0, 0L}
  365.                         };
  366.  
  367. things[kItemAsmDestLoc-1].refCon = (long)&AsmDestStr;
  368.  
  369. ShortToHexString(gILCBase, AsmDestStr);
  370.  
  371. if (HandleDialog(AsmEditNumFilter, things, nil, nil, kDLOG_ASMPREFS) == ok) {
  372.     HexStringToShort(AsmDestStr, (short *)&gILCBase);
  373.     }
  374. }
  375.  
  376. /* AsmEditNumFilter: filterProc for the asm prefs dialog */
  377.  
  378. static pascal Boolean AsmEditNumFilter(DialogPtr theD, EventRecord *thEv, short *iHit)
  379. {
  380. enum {
  381. kITEM_VALUE = 3
  382. };
  383.  
  384. GrafPtr    savePort;
  385. unsigned char    keypressed;
  386. register Boolean    retVal;
  387.  
  388. switch(thEv->what) {
  389.     case keyDown    :
  390.     case autoKey    :
  391.         keypressed = CHARFROMMESSAGE(thEv->message);
  392.         if ((keypressed >= 'a') && (keypressed <= 'z')) {
  393.             keypressed -= 'a' - 'A';    /* cambiare! */
  394.             CHARFROMMESSAGE(thEv->message) = keypressed;
  395.             }
  396.         if ((keypressed >= 32) && (keypressed != 0x7F) && ((thEv->modifiers & cmdKey) == 0)) {
  397.             *iHit = kITEM_VALUE;
  398.             return( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed, 1L, 0L, 0L) < 0L );
  399.             }
  400.         break;
  401.     case updateEvt:
  402.         if (theD != (DialogPtr)thEv->message) {
  403.             DoUpdate(thEv);
  404.             *iHit = kfakeUpdateItem;
  405.             return true;
  406.             }
  407.         break;
  408.     case activateEvt:
  409.         if (theD != (DialogPtr)thEv->message) {
  410.             DoActivate(thEv);
  411.             *iHit = kfakeUpdateItem;
  412.             return true;
  413.             }
  414.         break;
  415.     }
  416. GetPort(&savePort);
  417. SetPort(theD);
  418. retVal = StdFilterProc(theD, thEv, iHit);
  419. SetPort(savePort);
  420. return retVal;
  421. }
  422.  
  423. /* compareMnem: used to compare opcodes in the opcode table */
  424.  
  425. static int compareMnem(const void *opc1, const void *opc2)
  426. {
  427.  
  428. return(*(long *)opc1 - *(long *)opc2);
  429. }
  430.  
  431. /* cmpsymb: used to compare strings in the Symbol Table */
  432.  
  433. static int cmpsymb(const void *opc1, const void *opc2)
  434. {
  435. return(RelString(**(StringHandle *)opc1, **(StringHandle *)opc2, true, true));
  436. }
  437.  
  438. #endif
  439.  
  440.